/*
 * Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
 * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
 * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
 * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
 * Vestibulum commodo. Ut rhoncus gravida arcu.
 */

package com.mrd.gtimpframe.service.impl;

import com.github.pagehelper.PageInfo;
import com.mrd.base.Jqgrid;
import com.mrd.framework.config.web.json.Result;
import com.mrd.gtimpframe.entity.BizProtocolConfirm;
import com.mrd.gtimpframe.entity.Dictionary;
import com.mrd.gtimpframe.entity.GenProtocol;
import com.mrd.gtimpframe.entity.GenProtocolFee;
import com.mrd.gtimpframe.entity.GenProtocolProp;
import com.mrd.gtimpframe.entity.GenProtocolUnite;
import com.mrd.gtimpframe.repository.BizProtocolConfirmMapper;
import com.mrd.gtimpframe.repository.GenProtocolMapper;
import com.mrd.gtimpframe.repository.GenProtocolUniteMapper;
import com.mrd.gtimpframe.service.DictionaryService;
import com.mrd.gtimpframe.service.ProtocolConfirmService;
import com.mrd.gtimpframe.service.ProtocolService;
import com.mrd.util.CollectionUtil;
import com.mrd.util.LoginUtil;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

/**
 * Created by dengdc on 2017/8/8.
 */
@Service
public class ProtocolConfirmServiceImpl implements ProtocolConfirmService {
    @Resource
    private BizProtocolConfirmMapper bizProtocolConfirmMapper;
    @Resource
    private GenProtocolMapper genProtocolMapper;
    @Resource
    private DictionaryService dictionaryService;
    @Resource
    private GenProtocolUniteMapper genProtocolUniteMapper;
    @Resource
    private ProtocolService protocolService;

    /**
     * 获取确认报价页面的数据
     *
     * @param confirmId 确认报价ID
     * @param supId     报关行ID
     */
    @Override
    public Result getConfirmPageData(String confirmId, String supId) {
        List<BizProtocolConfirm> confirms = bizProtocolConfirmMapper.selectByUniteId(confirmId);
        if (CollectionUtil.isEmpty(confirms)) {
            return Result.newFailInstance("协议已被撤回，请联系管理员", "");
        }
        BizProtocolConfirm confirm = confirms.get(0);
        SimpleDateFormat yyyy_MM_dd = new SimpleDateFormat("yyyy-MM-dd");
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("confirmId", confirm.getId());
        dataMap.put("timeStart", yyyy_MM_dd.format(confirm.getStartTime()));
        dataMap.put("timeEnd", yyyy_MM_dd.format(confirm.getEndTime()));
        dataMap.put("supComName", confirm.getSupName());

        List<GenProtocol> protocols = genProtocolMapper.selectByUniteId(confirm.getProtocolUniteId());
        List<GenProtocolProp> props = new ArrayList<>();
        for (GenProtocol protocol : protocols) {
            props.addAll(protocol.getProps());
        }
        Map<String, List<GenProtocolProp>> classifyPropMap = classifyProp(props);
        Map<String, Object> detailMap = getDetailMap(protocols, classifyPropMap);
        dataMap.putAll(detailMap);
        System.out.println(dataMap);

        return Result.newSuccessInstance("完成查询", dataMap);
    }

    @Override
    public Page getSupConfirmGridData(Jqgrid jqgrid) {
        jqgrid.pageWithMybatis();
        jqgrid.sortWithMybatis();

        List<BizProtocolConfirm> bizProtocolConfirms = bizProtocolConfirmMapper
                .selectBySupId(LoginUtil.getLoginUser().getCompany().getId());

        List<Map> listMap = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat timeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (BizProtocolConfirm confirm : bizProtocolConfirms) {
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("id", confirm.getId());
            dataMap.put("startTime", sdf.format(confirm.getStartTime()));
            dataMap.put("endTime", sdf.format(confirm.getEndTime()));
            dataMap.put("status", confirm.getStatuLabel());
            dataMap.put("creator", confirm.getCreator());
            dataMap.put("createTime", timeFormat.format(confirm.getCreateTime()));
            dataMap.put("modifier", confirm.getModifier());
            Date mtime = confirm.getModifiyTime();
            dataMap.put("modifiyTime", mtime != null ? timeFormat.format(mtime) : "");
            dataMap.put("feeName", confirm.getProtocolUniteName());
            listMap.add(dataMap);
        }
        PageInfo pageInfo = new PageInfo(listMap);
        return new PageImpl(listMap, jqgrid.getPage(), pageInfo.getTotal());
    }

    @Override
    @Transactional
    public Result supDidConfirm(String uniteId) {
        BizProtocolConfirm confirm = bizProtocolConfirmMapper
                .selectByUnitIdAndSupId(uniteId, LoginUtil.getLoginUser().getCompany().getId(), "0");
        if (confirm == null) {
            return Result.newFailInstance("没有待确认的报价协议", "");
        }
        if (!BizProtocolConfirm.TO_BE_CONFIRM.equals(confirm.getStatus())) {
            return Result.newFailInstance("该报价已经确认过了", "");
        }
        confirm.setStatus(BizProtocolConfirm.CONFIRMED);
        confirm.setModifier(LoginUtil.getLoginAccount());
        confirm.setModifiyTime(new Date());
        bizProtocolConfirmMapper.updateByPrimaryKeySelective(confirm); //更新确认书
        genProtocolUniteMapper.updateStatusByPrimaryKey(confirm.getProtocolUniteId(), GenProtocolUnite.WAIT_EFFECTIVE);
        protocolService.updateAllUniteToEctStatus();
        return Result.newSuccessInstance("完成确认");
    }

    /**
     * 获取费用详细
     *
     * @param protocols       协议报价
     * @param classifyPropMap 报价协议属性分类
     */
    private Map<String, Object> getDetailMap(List<GenProtocol> protocols,
                                             Map<String, List<GenProtocolProp>> classifyPropMap) {
        Map<String, Object> dataMap = new HashMap<>();
        Map<String, List<Map<String, Object>>> impDetailMap = new HashMap<>();
        Map<String, List<Map<String, Object>>> expDetailMap = new HashMap<>();
        for (GenProtocol protocol : protocols) {
            if (isImportProtocol(protocol)) {
                getDetailListMap(classifyPropMap, impDetailMap, protocol);
            } else {
                getDetailListMap(classifyPropMap, expDetailMap, protocol);
            }
        }
        dataMap.put("impDetails", impDetailMap);
        dataMap.put("expDetails", expDetailMap);
        return dataMap;
    }

    /**
     * 传入不同的map，返回不同的结果
     */
    private void getDetailListMap(Map<String, List<GenProtocolProp>> classifyPropMap,
                                  Map<String, List<Map<String, Object>>> impDetailMap, GenProtocol protocol) {
        String feeName = protocol.getName();
        String feeTypeName = getProtocolFeeType(protocol.getId(), classifyPropMap);
        String countBy = getProtocolCountRule(protocol.getId(), classifyPropMap);
        List<Map<String, Object>> feeTypeDetails = impDetailMap
                .computeIfAbsent(feeTypeName, k -> new ArrayList<>());

        List<GenProtocolFee> fees = protocol.getFees();
        for (GenProtocolFee fee : fees) {
            Map<String, Object> singleDetailMap = new HashMap<>();
            boolean isCost = "1".equals(fee.getIeType()); // 是否是成本
            singleDetailMap.put("feeName", isCost ? feeName + "【收入】" : feeName + "【报价】");
            singleDetailMap.put("countBy", countBy);
            singleDetailMap.put("startCount", fee.getStartCount());
            singleDetailMap.put("startPrice", fee.getStartPrice());
            singleDetailMap.put("unitPrice", fee.getUnitPrice());
            singleDetailMap.put("capPrice", fee.getCapPrice());
            singleDetailMap.put("decript", protocol.getDescript());
            feeTypeDetails.add(singleDetailMap);
        }
    }

    /**
     * 判断是否是进口报价协议
     */
    private boolean isImportProtocol(GenProtocol protocol) {
        List<GenProtocolProp> props = protocol.getProps();
        for (GenProtocolProp prop : props) {
            if ("imp".equals(prop.getPropDtCode())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取协议的计费类型
     */
    private String getProtocolFeeType(String protocolId,
                                      Map<String, List<GenProtocolProp>> classifyPropMap) {
        List<GenProtocolProp> feeTypeProps = classifyPropMap.get("protocol_fee_type");
        for (GenProtocolProp prop : feeTypeProps) {
            if (protocolId.equals(prop.getProtocolId())) {
                return prop.getPropDtName();
            }
        }
        return "";
    }

    /**
     * 获取协议的计费类型
     */
    private String getProtocolCountRule(String protocolId,
                                        Map<String, List<GenProtocolProp>> classifyPropMap) {
        List<GenProtocolProp> countRuleProps = classifyPropMap.get("protocol_count_rule");
        Set<String> dtIds = new LinkedHashSet<>();
        for (GenProtocolProp prop : countRuleProps) {
            dtIds.add(prop.getPropDtId());
        }
        List<Dictionary> dictionaries = dictionaryService
                .selectByPrimaryKeyArray(dtIds.toArray(new String[0]));
        for (GenProtocolProp prop : countRuleProps) {
            if (protocolId.equals(prop.getProtocolId())) {
                for (Dictionary dt : dictionaries) {
                    if (dt.getId().equals(prop.getPropDtId())) {
                        return dt.getDescript();
                    }
                }
            }
        }
        return "";
    }

    /**
     * 对协议属性进行分类，按照字典组编码进行分类
     */
    private Map<String, List<GenProtocolProp>> classifyProp(List<GenProtocolProp> props) {
        Set<String> dtIds = new LinkedHashSet<>();
        for (GenProtocolProp prop : props) {
            dtIds.add(prop.getPropDtId());
        }
        List<Dictionary> dictionaries = dictionaryService
                .selectByPrimaryKeyArray(dtIds.toArray(new String[0]));
        for (GenProtocolProp prop : props) {
            dtIds.add(prop.getPropDtId());
        }

        Map<String, List<GenProtocolProp>> classifyMap = new HashMap<>();
        for (GenProtocolProp prop : props) {
            for (Dictionary dt : dictionaries) {
                String dtCode = dt.getGroupCode();
                if (!dt.getId().equals(prop.getPropDtId())) {
                    continue;
                }
                List<GenProtocolProp> bizTypeList = classifyMap
                        .computeIfAbsent("protocol_biz_type", k -> new ArrayList<>());
                List<GenProtocolProp> feeTypeList = classifyMap
                        .computeIfAbsent("protocol_fee_type", k -> new ArrayList<>());
                List<GenProtocolProp> countRuleList = classifyMap
                        .computeIfAbsent("protocol_count_rule", k -> new ArrayList<>());
                List<GenProtocolProp> ieTypeList = classifyMap
                        .computeIfAbsent("protocol_ie_rule", k -> new ArrayList<>());
                List<GenProtocolProp> dntTypeList = classifyMap
                        .computeIfAbsent("direct_transit_type", k -> new ArrayList<>());
                switch (dtCode) {
                    case "protocol_biz_type":
                        bizTypeList.add(prop);
                        break;
                    case "protocol_fee_type":
                        feeTypeList.add(prop);
                        break;
                    case "protocol_count_fee_rule":
                        countRuleList.add(prop);
                        break;
                    case "ie_type":
                        ieTypeList.add(prop);
                        break;
                    case "direct_transit_type":
                        dntTypeList.add(prop);
                        break;
                    default:
                }
            }
        }
        return classifyMap;
    }
}
